package ia04.agent.weather;

import ia04.util.StreamToString;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;

/* Current Conditions Phrases
 * Unknown = NO CHANGES
 * [Light/Heavy] Rain * = Pluie
 * [Light/Heavy] Snow * = Neige
 * Clear/Scattered Clouds = Soleil
 * Overcast | Partly/Mostly Cloudy = Couvert
 * DEFAULT = Soleil
 * OTHERS = Orage
 */

public class BehavUpdateWeather extends TickerBehaviour {

	private WeatherHandler handler;
	private HttpGet httpget;

	// For Proxy
	private DefaultHttpClient httpclient;
	private HttpHost proxy;

	final static long period = 3600000; // 1 hour = 60*60*1000 ms
	final String serviceRestUrl = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=zmw:00000.1.07057";
	final boolean bUseProxy = false;

	public BehavUpdateWeather(Agent a)
	{
		super(a, period);

		handler = new WeatherHandler();
		
		// Create client
		httpclient = new DefaultHttpClient();
		
		if(bUseProxy)
		{
			// Define proxy
			proxy = new HttpHost("proxyweb.utc.fr", 3128);
			httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
		}
		
		// Prepare a request object
		httpget = new HttpGet(serviceRestUrl);

		updateNeeded();
	}

	@Override
	public void onTick()
	{
		updateNeeded();
	}
	
	private void updateNeeded()
	{
		// Update weather
		// Execute the request
		try {
			String xmlString = "";
			HttpResponse response = httpclient.execute(httpget);
			// Examine the response status
			System.out.println(response.getStatusLine());
			// Get hold of the response entity
			HttpEntity entity = response.getEntity();
			// If the response does not enclose an entity, there is no need to worry about connection release
			if (entity != null)
			{
				InputStream instream = entity.getContent();
				xmlString = StreamToString.convertStreamToString(instream);
			}
			if(!xmlString.isEmpty())
			{
				InputSource resourceContent = new InputSource();
				resourceContent.setCharacterStream(new StringReader(xmlString));
				// Outputting the content of a Web page
				XMLReader saxReader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
				saxReader.setContentHandler(handler);
				saxReader.parse(resourceContent);
				if(updateWeather())
				{
					broadcastWeather();
				}
			}
		} catch (ClientProtocolException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}

	private boolean updateWeather()
	{
		if(handler != null)
		{
			String newWeather = handler.getWeather();

			System.out.println("BEFORE UPDATE: " + ((AgentWeather)myAgent).getWeather() + " & CURRENT WEATHER: " + newWeather);
			
			// No changes if empty or unknown
			if(newWeather.isEmpty() || newWeather.equals("Unknown")) return false;
			
			if(newWeather.contains("rain")) newWeather = "Pluie";
			else if(newWeather.contains("snow")) newWeather = "Neige";
			else if(newWeather.equals("Clear") || newWeather.equals("Scattered Clouds")) newWeather = "Soleil";
			else if(newWeather.equals("Overcast") || newWeather.equals("Partly Cloudy") || newWeather.equals("Mostly Cloudy"))
				newWeather = "Couvert";
			else newWeather = "Orage";
			((AgentWeather)myAgent).setWeather(newWeather);
	
			System.out.println("AFTER UPDATE: " + ((AgentWeather)myAgent).getWeather());
			return true;
		}
		return false;
	}
	
	private void broadcastWeather()
	{
		// Get subscribers
		ArrayList<AID> subscribedAgents = ((AgentWeather)myAgent).getSubscribedAgents();
		
		if(!subscribedAgents.isEmpty()) return;

		// Build answer
		String answer = ((AgentWeather)myAgent).getWeather();
		
		// Build message
		ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
		msg.setContent(answer);
		
		for(int i = 0; i < subscribedAgents.size(); ++i)
		{
			msg.addReceiver(subscribedAgents.get(i));
		}
		
		// Send message
		myAgent.send(msg);
	}

}
